#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include<sys/types.h>
#include <fcntl.h>
#define NUM 10000
#include <time.h>
#include <sys/mman.h>

typedef struct Student{
    char name[20];
    int age;
    double score;
}stu;

int main(int argc,char* argv[])
{

    int fd;
    fd =open("stv.dat",O_RDWR);

    //如果Linux操作系统上的函数 （System call系统调用） 执行失败，会自动把错误信息存放到操作系统的某个位置  可以直接用printf("%m")输出出来
    if (-1==fd)
    {
        printf("打开%s失败：%m\n",argv[1]);
        printf("尝试创建文件\n");
        //位运算相对比较精密
        fd =open("stv.dat",O_RDWR|O_CREAT,0666);
        if (-1==fd)
        {
            printf("创建%s失败：%m\n",argv[1]);
            exit(-1);
        }
        printf("创建文件成功\n");
    }
    printf("打开文件成功\n");
   //调整文件大小
    int r = ftruncate(fd,sizeof(stu) * NUM);
    if (-1==r)
    {
        printf("调整文件大小失败\n");
        close(fd);
        exit(-1);
    }

    printf("调整文件大小成功\n");
    //文件映射成虚拟内存
    struct Student *p = mmap(NULL, NUM*sizeof(stu), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (p == MAP_FAILED) {
        perror("mmap");
        close(fd);
        exit(EXIT_FAILURE);
    }

    if (NULL==p)
    {
        printf("映射失败：%m\n");
        close(fd);
        exit(-1);
    }
    printf("映射成功\n");
    struct  Student * pTemp = p;
    struct timeval oldtime,newtime;
    gettimeofday(&oldtime,NULL);
    for (int i=0;i<NUM;i++)
    {
        stu s={"xiaowang",i,10};
        memcpy(pTemp,&s,sizeof(s));
        pTemp++;
    }
    gettimeofday(&newtime,NULL);
    printf("%d %d",newtime.tv_sec-oldtime.tv_sec,newtime.tv_usec-oldtime.tv_usec);
    //解除映射
    munmap(p,NUM*sizeof(stu));
    //关闭文件
    close(fd);



    return 0;
}